(post
 :title "8sync participates in the Lisp Game Jam with Mudsync"
 :date (make-date* 2016 05 11 17 30)
 :tags '("lisp-game-jam" "mudsync" "actors")
 :slug "mudsync-lisp-game-jam"

 (p [Hello, hello!
     Over the last week and a half, 8sync participated in the
     ,(anchor [Spring 2016 Lisp Game Jam]
              "https://itch.io/jam/spring-2016-lisp-game-jam").
     In short, I had ten days to build a game, so I decided to build a
     ,(anchor [MUD] "https://en.wikipedia.org/wiki/MUD")
     on top of 8sync.
     And so, ,(anchor [mudsync] "https://notabug.org/cwebber/mudsync/")
     was born!])

 (code-block "> go east
**Smoking Parlor**
  This room looks quite posh.  There are huge comfy seats you can sit in
if you like.
  Strangely, you see a large sign saying \"No Smoking\".  The owners must
have installed this place and then changed their mind later.
  There's a door to the west leading back to the grand hallway, and
a nondescript steel door to the south, leading apparently outside.
You see here: a comfy leather chair, a plush leather sofa, Ford Prefect and a
bar stool.
> sit in the chair
You sink into the comfy leather chair.
> say Ahhhhhh, this is the life!
paroneayea says: Ahhhhhh, this is the life!")

 (h2 [How'd it go?])

 (p [I'm happy to say that mudsync was successful overall.
     The end released project includes a fairly solid, live hackable
     game engine for multiplayer interactive fiction.
     This ended up being more of a piece of infrastructure to
     ,(em [build]) games rather than being a nice game itself, but
     it does ship with a mini-world called "Hotel Bricabrac" which
     has some interesting things, but is more of a tech demo.
     Most importantly, I feel like mudsync is a really nice foundation
     for future games, and the amount of world building I did do in it
     was a joy to put together.
     So!  More of that in the future?])

 (p [Mudsync also made great use of 8sync's new actor model subsystem,
     which will publicly premiere in the upcoming 0.2.0 release.])

 (h2 [Why participate in the game jam?])

 (p [At first participating in the game jam may sound merely like an
     exercise in fun, and of course it was this too, but greater ambitions
     were also at play.
     I have plans to use 8sync for some larger projects involving federated
     networks, and I wanted to be sure that the technology worked well
     enough to invest my time by building something more complicated.
     Happily, all seems to have gone well;
     I am feeling much more confident in 8sync now having completed the jam
     and am looking forward to my larger projects with it.
     And along other federation-related lines, I've long been interested in
     the overlap between the type of federation-related work I am
     persuing with the
     ,(anchor [ActivityPub standard] "https://www.w3.org/TR/activitypub/")
     MUDs, and the actor model of programming.
     MUDS, the actor model, and
     ,(anchor [ActivityStreams]
              "https://www.w3.org/TR/activitystreams-core/")
     (the syntactic basis upon which ActivityPub rests)
     all share a subject-predicate-object syntax and use message passing as
     a primary communication mechanism.
     And lest it sound like I've gone completely off my rocker
     (maybe I have, of course)
     I might note that research in MUDs as a decentralized mechanism of
     communication was very high before the web took over everything,
     and even an active topic in a couple of research labs!
     (I recommend checking out the
       ,(anchor [Design Requirements for Network Spaces]
                "http://saraswat.org/desiderata.html")
       document to get a sense of this.)
     So I figured implementing a MUD might help me better think through
     some of this space, and it did!])

 (p [Furthermore, 8sync itself owes part of its existence to a much older
     interest of mine in creating networked games.
     ,(anchor [XUDD] "http://xudd.readthedocs.io/en/latest/"),
     the actor model system I wrote in Python and which preceded my
     thoughts on how to build 8sync, originally stood for
     "eXtensible User Dungeon Design"
     (but I gave it a sillier acronymn when its goals shifted).
     I haven't lost interest in how to design such systems, and the
     implications of them fueled a lot of my reading in this area.])

 (p [Plus, it sounded like a whole lot of fun!])

 (h2 [What does it look like?])

 (p [From a player's perspective, mudsync is your classic MUD-over-telnet.
     There are some things missing, but it works: you can walk around from
     room to room, interactive with objects and other players, and so on.])

 (p [From an administrator / hacker's perspective, mudsync is much more
     interesting.
     You write out a "game spec" like the following
     (which is borrowed from
        ,(anchor [real game code]
                 "https://notabug.org/cwebber/mudsync/src/master/worlds/bricabrac.scm")):])

 (code-block-scheme
  "(define lobby
  (lol  ; just a simple 'list of lists' macro
   ;; Starting place for players
   ('room:lobby
    <room> #f
    #:name \"Hotel Lobby\"
    #:desc
    \"  You're in some sort of hotel lobby.  You see a large sign hanging
over the desk that says \\\"Hotel Bricabrac\\\".  On the desk is a bell
that says \\\"ring for service\\\".  Terrible music plays from a speaker
somewhere overhead.
  The room is lined with various curio cabinets, filled with all sorts
of kitschy junk.  It looks like whoever decorated this place had great
ambitions, but actually assembled it all in a hurry and used whatever
kind of objects they found lying around.
  There's a door to the north leading to some kind of hallway.\"
    #:exits
    (list (make <exit>
            #:name \"north\"
            #:to 'room:grand-hallway)))
   ;; Summons a clerk if a player does 'ring bell'
   ('thing:lobby:bell
    <summoning-bell> 'room:lobby
    #:name \"a shiny brass bell\"
    #:goes-by '(\"shiny brass bell\" \"shiny bell\" \"brass bell\" \"bell\")
    #:desc \"  A shiny brass bell.  Inscribed on its wooden base is the text
\\\"ring me for service\\\".  You probably could \\\"ring the bell\\\" if you 
wanted to.\"
    #:summons 'npc:break-room:desk-clerk)))")

 (p [This builds the kind of world you might expect from the above:])

 (code-block "> look
**Hotel Lobby**
  You're in some sort of hotel lobby.  You see a large sign hanging
over the desk that says \"Hotel Bricabrac\".  On the desk is a bell
that says \"ring for service\".  Terrible music plays from a speaker
somewhere overhead.
  The room is lined with various curio cabinets, filled with all sorts
of kitschy junk.  It looks like whoever decorated this place had great
ambitions, but actually assembled it all in a hurry and used whatever
kind of objects they found lying around.
  There's a door to the north leading to some kind of hallway.
You see here: a curio cabinet, a shiny brass bell, the Hotel Bricabrac sign, a
frumpy fellow and sign-in form.
> look at bell
  A shiny brass bell.  Inscribed on its wooden base is the text
\"ring me for service\".  You probably could \"ring the bell\" if you
wanted to.
> ring the bell
*ring ring!*  You ring the bell!
  Suddenly, a uniformed woman rushes into the room!  She's wearing a
badge that says \"Desk Clerk\".
  \"Hello, yes,\" she says between breaths, \"welcome to Hotel Bricabrac!
We look forward to your stay.  If you'd like help getting acclimated,
feel free to ask me.  For example, 'ask clerk about changing name'.
You can ask me about the following:
'changing name', 'common commands', and 'about the hotel'.\"")

 (p [(I inserted the ">" characters to make where the input was a bit
      clearer, but otherwise that's verbatim output from the game.)])

 (p [What's nice is that you can live hack everything that's going on.
     And by that of course I mean the kind of usual nice live hacking
     you have going on with 8sync and Guile... but it's not only that!
     Consider the following challenge: you've just tweaked the description
     of the room your friends are hanging out in, but you already
     ,(em [have]) a room set up in the game's universe, so how on earth
     can you replace it?
     Luckily Mudsync provides a nice protocol for replacing objects,
     and even provides a nice utility to inject it into the currently
     running game (the actors know how to "transfer important details",
     in this case, the participants in the room):])

 (code-block-scheme "(inject-gameobj! game-spec 'room:lobby)")

 (p [Obviously, you don't want to do this for anything other than live
     hacking.
     But it ,(em [is nice]) that you can live modify how things are
     running in the game.
     For example, at one point a player asked me how they could "emote"
     in the game, and we didn't have an emote command, so I added it
     and told them, and then we all happily did some emote'ing.
     At another point a player said they felt bad for the desk clerk
     and wanted a way to dismiss her so she wouldn't have to hang
     around the desk, so I added a dismiss command where she'll
     thank the player and "run off to do something important"
     (as it turns out, doing something important means to go smoke in the
     employee break room).])

 (h2 [A story about stories])

 (p [So, speaking of that, the "main game" that ships with Mudsync right
     now is a little mo... hotel named "Hotel Bricabrac" full of various
     strange and fun things (though, not as many as I would like).
     Unfortunately, it lacks any significant story.
     There's something that almost resembles a story, and which players
     seemed to like: the desk clerk, upon ringing the bell, arrives,
     but quickly becomes bored, starts fidgeting distractedly, and
     eventually leaves.
     When I first started coding this, I had envisioned the character as
     perhaps a disaffected and incompetent teenager, but as I was playing
     around I started to feel empathy for them... it really ,(em [was])
     a boring job that they had, and newcomers ringing the bell all the
     time ,(em [would]) get annoying.
     Thus, if you explore well enough, you might find the
     "employee break room", a cage affixed to the exterior of the building.
     Whenever the clerk leaves her post, she goes here to smoke and
     check her phone and slack off.
     But if you talk to her enough in this off-duty space, she'll tell you
     that she's a student studying high energy particle physics, that she's
     underpaid, but she's working the job because she doesn't have many other
     options and her student loans are crushing her.
     So she was never really incompetent after all, just overqualified,
     bored, and, well, still disaffected.
     Some players seemed to enjoy that and expressed empathy for the character
     (though it didn't seem to stop them from ringing the bell to provoke
     a response from her).
     I was glad about that, and I wish I had more time to script in more
     things like this.])

 (p [Indeed, my original ambitions were to build a full and immersive
     game as part of the game jam.
     I sketched in a notebook a layout for a haunted mansion or college
     campus.
     My original vision for the jam was that players would be collaborating
     in exploring an area on figuring out how to help various ghosts be put
     to rest.
     You'd find out what's binding them to this world and help them resolve
     their problems, and you as a player would have an "achievements" list
     showing off just how many interesting things you had done in the
     world.
     Unfortunately (though not surprisingly), building the engine itself
     ended up being enough work that I didn't have a lot of time for
     content.
     Thus the experimental little world where I was testing various game
     mechanics became the actual deliverable of a demo-world to be
     played.])

 (p [In the end, that's probably not the worst situation.
     I feel I have a good design on which future games could be built.
     And despite the chaos of it, players did seem to have a lot of fun
     (I think at one point we had about 8 players or so on the game who
     were hanging out and mostly socializing).
     The chaotic gathering place on some mysterious property atmosphere
     looks a lot like LambdaMOO, and as
     ,(anchor [LambdaMOO enthusiast Rob Myers]
              "https://robmyers.org/lambdamoo/")
     said to me at one point,
     "Themeliness is next to timeliness."
     It's not such a bad start!
     Though I do hope to have more interesting worlds to show in the
     future.])

 (h2 [Challenges])

 (p [No sprint like this is without its challenges.
     Here were mine:])

 (ul (li [It was really hard to decide what "flavor" of sentence
          parsing to go with.
          Basically you can either have more rich sentences which require
          a lot of complicated parsers, but then you can say complicated
          things like "Put the melon in the fruit basket."
          (Zork/ZIL/Z-Machine type single-player interactive fiction
          games tend to go like this.)
          Or you can go with more predictable but limited parser
          and parse more basic sentences like "put melon in fruit basket".
          The former lends itself to more immersive gameplay.
          The latter is faster, more predictable, and works better for
          either combining with non-text interfaces (maybe a web UI)
          and could concievably work with a federated game.
          I spent some time
          ,(anchor [agonizing over this]
                   "https://identi.ca/cwebber/comment/mo2uRHqIQAKXsFYbYev46g").
          In the end I built kind of a hybrid: actors select from
          a few prebuilt "rich" command processors which handle all the
          basic cases you might want.])
     (li [8sync relies heavily on delimited continuations.
          However, sometimes if scheme calls C which then calls out to
          scheme again in Guile, things break.
          A few things caused this, including using the "@@" special
          form to try to get around dependency loops lazily.
          Most significantly, since 8sync's actor model system uses
          GOOPS, I learned the hard way that GOOPS being very C based
          in Guile 2.0 means that I had to forego many interesting
          GOOPS features, like generic methods or accessors.
          Once I realized this, things went a lot more smoothly,
          and I didn't really ,(em [need]) these features... but sometimes
          I wished I had them.])
     (li [You might say, "but Guile 2.2's GOOPS was rewritten in scheme!"
          And you'd be right.
          Unfortunately, I
          ,(anchor [uncovered a pretty critical bug]
                   "https://lists.nongnu.org/archive/html/bug-guile/2016-04/msg00004.html")
          with GOOPS and Guile 2.2, and didn't have time to look into it
          seriously.
          Again, not a huge deal, but it did take up some time to look into.])
     (li [I hit a really weird SIGABRT issue in 8sync's actor model.
          Initially
          ,(anchor [I thought it was a Guile issue]
                   "https://lists.nongnu.org/archive/html/bug-guile/2016-05/msg00003.html"),
          but it turned out I
          ,(anchor [just didn't understand some things about how prompts
                    and exceptions work]
                   "https://lists.nongnu.org/archive/html/bug-guile/2016-05/msg00004.html").])
     (li [I really wanted to have a nice text formatter, but I ran out
          of time to integrate one.
          (If you talk to the hotel owner in the lobby of Hotel
          Bricabrac, you'll find he complains about this kind of
          indirectly, expressing my wishes to explore something along
          the lines of
          ,(anchor [Skribilo] "http://www.nongnu.org/skribilo/") or
          ,(anchor [fmt] "http://synthcode.com/scheme/fmt/").
          Alas!  No time for it...)])
     (li [Again, I would have loved to have more time to build a more
          coherent story.
          But time is always a challenge in these things!]))

 (h2 [What's next?])

 (p [So mudsync will be a background hacking task for me probably
     for a while, something to hack on for my and friends' amusement
     every now and then.
     I may end up writing some small and interesting stories.
     But it won't be my main project.])

 (p [But it probably will be a basis for research (and fun)
     for me.
     It's a nice system to test out ideas in.
     And I'll probably add some cool optional components, like
     persistent-world-supporting databases.
     (Maybe even player-scripted items?
     Unlikely in that it would require a carefully crafted sandboxed
     execution environment, but don't think I haven't been thinking
     about it...!)])

 (p [In the meanwhile, if you want to check it out, the
     ,(anchor [source is available]
              "https://notabug.org/cwebber/mudsync/").
     Patches most welcome!
     And if you hop in #8sync on irc.freenode.net, maybe you can
     find the address of the current dev server!])

 (p [Thanks to Rob Myers and Jason Self, who both know a lot more about
     interactive fiction than I do and answered a lot of questions
     and offered ideas.
     Thanks also to everyone who gave the game a try.
     I hope it was as fun for you as it was for me!])

 (p [Happy hacking...]))

